(library (grid-gen Osher)
  (export Osher:dF)
  (import (guile)
          (grid-gen main)
          (grid-gen math)
          (srfi srfi-1)
  )

(define chi `(/ 1.0 3.0))
(define beta `(/ (- 3.0 ,chi) (- 1.0 ,chi)))

(define minmod (lambda (x y)
  `(* 0.5 (+ (sign ,x) (sign ,x)) (min (abs ,x) (abs ,y)))
))


(define ddF (lambda (dFl m)
  (map (lambda (dc)
         (let* ((lam (cadr dc))
                (cf `(* (max (* ,lam ,m) 0.0) ,m))
                (dF (car dc))
               )
           (mul2 dF cf)
         )
       )
       dFl
  )
))

(define Osher:dF1
  (lambda (d gr i)
    (letrec* ((im  (replace-el i d (- (list-ref i d) 1)))
              (ip  (replace-el i d (+ (list-ref i d) 1)))

              (dFl_i-1/2 (ADV:dFl d gr im))
              (dFl_i+1/2 (ADV:dFl d gr i ))
              (dFl_i+3/2 (ADV:dFl d gr ip))
           
              (v_i+3/2 (ADV:vm (gr 'var-l ip d) (gr 'var-r ip d)))
              (v_i+1/2 (ADV:vm (gr 'var-l i  d) (gr 'var-r i  d)))
              (v_i-1/2 (ADV:vm (gr 'var-l im d) (gr 'var-r im d)))
           
              (dFl-_i+3/2 (ddF dFl_i+3/2 -1.0))
              (dFl-_i+1/2 (ddF dFl_i+1/2 -1.0))
              (dFl+_i+1/2 (ddF dFl_i+1/2  1.0))
              (dFl+_i-1/2 (ddF dFl_i-1/2  1.0))
              
              (limiter (lambda (f1 f2)
                (mul2 0.5
                      (add (mul2 `(+ 1.0 ,chi) 
                                  (map-ar minmod f2 (mul2 beta f1))
                           )
                           (mul2 `(- 1.0 ,chi)
                                  (map-ar minmod (mul2 beta f2) f1)
                           )
                      )
                )
              ))
             )
           (mul2 -0.25
                 (apply add
                   (map (lambda (dl)
                          (let ((dF-_i+3/2 (list-ref dl 0))
                                (dF-_i+1/2 (list-ref dl 1))
                                (dF+_i+1/2 (list-ref dl 2))
                                (dF+_i-1/2 (list-ref dl 3))
                               )
                            ;(add (limiter dF+_i-1/2 dF+_i+1/2)
                            ;     (mul2 -1.0 (limiter dF-_i+1/2 dF-_i+3/2))
                            ;)
                            (add (mul2 `(+ 1.0 ,chi)
                                        (map-ar minmod dF+_i+1/2
                                                       (mul2 beta dF+_i-1/2)
                                        )
                                 )
                                 (mul2 `(- 1.0 ,chi)
                                        (map-ar minmod dF+_i-1/2
                                                       (mul2 beta dF+_i+1/2)
                                        )
                                 )
                                 (mul2 `(* -1.0 (- 1.0 ,chi))
                                        (map-ar minmod dF-_i+3/2
                                                       (mul2 beta dF-_i+1/2)
                                        )
                                 )
                                 (mul2 `(* -1.0 (+ 1.0 ,chi))
                                        (map-ar minmod dF-_i+1/2
                                                       (mul2 beta dF-_i+3/2)
                                        )
                                 )
                            )
                          )
                        )
                        (zip dFl-_i+3/2 dFl-_i+1/2 dFl+_i+1/2 dFl+_i-1/2)
                   )
                 )
           )
    )
  )
)

)

(import (grid-gen main))
(set-comp-order (+ 1 (comp-order)))
(set! ADV:dF1 Osher:dF1)
